﻿using Windows.Storage;
using Microsoft.Extensions.Options;

namespace DimensionsHelper.Client.WinUi.Services;

public class LocalSettingsService : ILocalSettingsService
{
    private const string DefaultApplicationDataFolder = "DimensionsHelper/ApplicationData";
    private const string DefaultLocalSettingsFile = "LocalSettings.json";
    private readonly string _applicationDataFolder;

    private readonly IFileService _fileService;

    private readonly string _localApplicationData =
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

    private readonly string _localSettingsFile;
    private bool _isInitialized;

    private Dictionary<string, object?> _settings;

    public LocalSettingsService(IFileService fileService, IOptions<LocalSettingsOptions> options)
    {
        _fileService = fileService;
        LocalSettingsOptions opt = options.Value;

        _applicationDataFolder = Path.Combine(_localApplicationData,
            opt.ApplicationDataFolder ?? DefaultApplicationDataFolder);
        _localSettingsFile = opt.LocalSettingsFile ?? DefaultLocalSettingsFile;

        _settings = new Dictionary<string, object?>();
    }

    public async Task<string?> ReadSettingAsync(string key)
    {
        if (RuntimeHelper.IsMSIX)
        {
            if (ApplicationData.Current.LocalSettings.Values.TryGetValue(key, out object? obj) && obj is string value)
            {
                return value;
            }
        }
        else
        {
            await InitializeAsync();

            if (_settings.TryGetValue(key, out object? obj) && obj is string value)
            {
                return value;
            }
        }

        return null;
    }


    public async Task<T?> ReadSettingAsync<T>(string key, JsonTypeInfo<T> jsonTypeInfo)
    {
        string? text = await ReadSettingAsync(key);

        if (!string.IsNullOrEmpty(text))
        {
            return JsonSerializer.Deserialize(text, jsonTypeInfo);
        }

        return default;
    }


    public async Task SaveSettingAsync<T>(string key, T value)
    {
        string stringify;

        if (value is string text)
        {
            stringify = text;
        }
        else
        {
            stringify = JsonSerializer.Serialize(value);
        }

        if (RuntimeHelper.IsMSIX)
        {
            ApplicationData.Current.LocalSettings.Values[key] = stringify;
        }
        else
        {
            await InitializeAsync();
            _settings[key] = stringify;
            await Task.Run(() => _fileService.Save(_applicationDataFolder, _localSettingsFile, _settings));
        }
    }


    public async Task SaveSettingAsync<T>(string key, T value, JsonTypeInfo<T> jsonTypeInfo)
    {
        string stringifyValue = JsonSerializer.Serialize(value, jsonTypeInfo);
        await SaveSettingAsync(key, stringifyValue);
    }

    private async Task InitializeAsync()
    {
        if (!_isInitialized)
        {
            _settings = await Task.Run(() => _fileService.Read<Dictionary<string, object?>>(_applicationDataFolder,
                _localSettingsFile)) ?? new Dictionary<string, object?>();
            _isInitialized = true;
        }
    }
}